var map;
var hero;
var data;
var medaltracker;
var pickups = new Array();
var enemies = new Array();
var emiters = new Array();
var m_start = new Array(2);
var m_end = new Array(2);
var wave = 0;
var found_reverse = false;
var game_start = false;
var NO = 0; 
var WON = 1; 
var LOST = 2;
var game_over = NO;


/*fills up the pickups array with the pickups at given locations*/
function PatternGenerator(){
    var i = 1;
    if(wave == 0){
        obj = new Pickup(data.img_pickup, [0,0]);
        pickups.push(obj);
        wave++;
        return;
    }
    if(wave % 2 == 0){
        map.vel[0] = 2;
        map.vel[1] = 2;
    }else{
        map.vel[0] = 0;
        map.vel[1] = 0;
    }
    lines = RandChoice(data.patterns).responseText.split('\n'); //data.txt_pattern.responseText.split('\n');
    npicks = parseInt(lines[0]);
    if(enemies.length > 5){
        emiters.push(new Emiter([0,0], [0, 0], "pup_blast", false, true));
    }
    while(i <= npicks){
        coords = lines[i].split(' ');
        //var x = map.pos[0] + parseInt(coords[0]);
        //var y = map.pos[1] + parseInt(coords[1]);
        var x =  parseInt(coords[0]);
        var y =  parseInt(coords[1]);
        emiters.push(new Emiter([x,y], [0,0], "pickup", false, true));
        i++;
    }
    ne = parseInt(lines[i]);
    while(i < (npicks+1+ne)){
        i++;
        coords = lines[i].split(' ');
//        var x = map.pos[0] + parseInt(coords[0]);
//        var y = map.pos[1] + parseInt(coords[1]);        
        var x = parseInt(coords[0]);
        var y = parseInt(coords[1]);        
        if(wave > 4){
            emiters.push(new Emiter([x,y], [0,0], RandChoice(["e2", "e3"]), false, true));
        }else{
            emiters.push(new Emiter([x,y], [0,0], "e2", false, true));
        }
    }
    wave++;
}

function Game(){
    data = new Data();
    map = new Map(canvas.width/2, canvas.height/2, 200);
    hero = new Hero();
    medaltracker = new MedalsTracker();
    this.update = update; 
    this.draw = function(){
    }
    this.onMouseMove = onMouseMove;
    this.onMousePress = onMousePress;
}

function onMouseMove(e){
	var posx = 0;
	var posy = 0;

    if (e.pageX || e.pageY){
        posx = e.pageX;
        posy = e.pageY;
    }
    else if (e.clientX || e.clientY){
        posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
    }
    // posx and posy contain the mouse position relative to the document
    // Do something with this information
    
    m_end[0] = (posx-canvas.offsetLeft); 
    m_end[1] = (posy-canvas.offsetTop);
}

function onMousePress(evnt){
    if(!game_start){
        game_start = true;
        pbutton.style.visibility="visible";
        return;
    }
    if(game_over == LOST){
        game_over = NO;
        hero.pickups = 0;   //set score to 0
        gmesg.style.backgroundColor="#76d776";
        gmesg.style.visibility = "hidden";
    }
    if(hero.vel[0] + hero.vel[1] == 0){ //now trying to set velocity.
        var xd = m_start[0] - m_end[0]; 
        var yd = m_start[1] - m_end[1]; 
        var val = xd * xd + yd * yd;
        hero.vel[0] = hero.speed * -xd/Math.sqrt(val);
        hero.vel[1] = hero.speed * -yd/Math.sqrt(val);
    }
}

function update(){
    var i;
    if(pbutton.innerHTML == "&gt;"){
        return;
    }
    if(data.done == 0){
        if(!game_start){
            ctx.drawImage(data.img_logo, canvas.width/2-150, 60);
            gmesg.innerHTML = "<i> Click to Start </i>";
            medaltracker.drawMedals();
            pbutton.style.visibility="hidden";
            return;
        }
        if(game_over == WON ){
            //ctx.drawImage(data.img_logo, canvas.width/2-150, 60);
            gmesg.innerHTML = "<b> You WIN !!</b>";
            medaltracker.drawMedals();
            return;
        }
        if(game_over == LOST){
            //ctx.drawImage(data.img_logo, canvas.width/2-150, 60);
            gmesg.style.backgroundColor="#f64663";
            gmesg.innerHTML = "<b> You Got Crushed!!</b> <br><i>Click to start with 0 score. Refresh page to restart</i></br>";
            gmesg.style.visibility = "visible";
            medaltracker.drawMedals();
            return;
        }

        gmesg.style.visibility = "hidden";
        if(!found_reverse && pickups.length == 0){
            PatternGenerator();
            medaltracker.drawMedals();
            hero.tmn++; //we assume he completes without any issues.
        }
        medaltracker.update();
        if(map.update()){
            hero.crushmiss++;
        }
        hero.update();
        hx = hero.pos[0] - map.pos[0];
        hy = hero.pos[1] - map.pos[1];
        if(hero.bCollision([0,0], [canvas.width, canvas.height])){
            //data.snd_crush.play();
            //hero.pickups--;
            hero.crushmiss = 0;
            game_over = LOST;
            //emiters.push(new Emiter([hx, hy], [2,2], "hero", false, false));
        }
        var etmp = new Array();
        for(i in enemies){
            if(enemies[i].moves)
                enemies[i].update();
            if(hero.cCollision(enemies[i])){
                hero.tmn = 0;
                hero.pickups-=10;
                data.snd_crush.play();
                if(enemies[i].moves)
                    emiters.push(new Emiter([hx,hy], [0,0], "e3", false, false));
                else
                    emiters.push(new Emiter([hx,hy], [0,0], "e2", false, false));
            }else{
                etmp.push(enemies[i]);
            }
        }
        enemies = etmp;

        var tmp = new Array();
        for(i in pickups){
            if(hero.cCollision(pickups[i])){
                hero.pickups++;
                data.snd_pick.play();
                emiters.push(new Emiter([hx,hy], [0,0], "pickup", false, false));
                if(pickups[i].power_type == "pup_blast"){ //clear out all enemies
                    for(var j in enemies){
                        emiters.push(new Emiter(enemies[j].pos, [0,0], "e2", false, false));
                    }
                    hero.pickups += enemies.length; //score points for killing enemies
                    enemies = new Array();
                }
            }else{
                if(pickups[i].start_time){
                    if(new Date().getTime() - pickups[i].start_time.getTime() > 120 * 60){ //wait 2 minute
                        continue;
                    }
                }
                tmp.push(pickups[i]);
            }
        }
        pickups = tmp;
        //for the guide drawing
        m_start[0] = hero.pos[0];
        m_start[1] = hero.pos[1];
        if(emiters.length < 7 && (hero.vel[0] || hero.vel[1])){
            emiters.push(new Emiter([hx,hy], [-hero.vel[0], -hero.vel[1]], "smoke", false, false));
        }
        //drawing.. 
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        map.draw('rgba(100, 100, 200, 255)', 'rgba(0, 0, 0, 255)');
        hero.draw('rgba(100, 100, 200, 255)', 'rgba(0, 0, 0, 255)');
        for (i in pickups){
            pickups[i].draw("rgba(20,100, 10, 255)", "rgb(10, 50, 5, 255)");
        }
        for (i in enemies){
            enemies[i].draw("rgba(20,100, 10, 255)", "rgb(10, 50, 5, 255)");
        }
        found_reverse = false;
        tmp = new Array();
        for(i in emiters){
            if(emiters[i].reverse){
                found_reverse = true;
            }
            emiters[i].update();    //updating emiters and drawing as well
            if(emiters[i].done){
                if(emiters[i].reverse){ //this was added for spawning stuff
                    var x = emiters[i].pos[0];
                    var y = emiters[i].pos[1];
                    obj = new Pickup(data.getImage(emiters[i].img), [x,y]);
                    if(emiters[i].img == "e2" || emiters[i].img == "e3"){
                        obj.r = 10;
                        if(emiters[i].img == "e3"){
                            obj.moves = true;
                        }
                        enemies.push(obj);
                    }else if(emiters[i].img == "pickup" || emiters[i].img == "pup_blast"){
                        if(emiters[i].img == "pup_blast"){
                            obj.start_time = new Date();
                            obj.power_type = emiters[i].img;
                            obj.r = 15;
                        }
                        pickups.push(obj);
                    }
                }
                continue;
            }
            tmp.push(emiters[i]);
        }
        emiters = tmp;
        ctx.globalAlpha=1;
        if(hero.vel[0] + hero.vel[1] == 0){
            //draw the guide line    
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.moveTo(m_start[0], m_start[1]);
            ctx.lineTo(m_end[0], m_end[1]);
            ctx.stroke();
        }
        ctx.font = "16pt Arial";
        ctx.fillText("Score: " + hero.pickups, 0, 20);
    }
}

/*------------------------data.js-------------------*/
//class to load all the data files.
function Data(){
    this.numpatterns = 4;
    this.numimages = 7; 
    this.numsounds = 1;
    this.done = this.numpatterns + this.numimages;
    
    this.snd_pick = new Audio();
    this.snd_pick.src = "data/pick.ogg";
    this.snd_pick.load();

    this.snd_crush = new Audio();
    this.snd_crush.src = "data/crash.ogg";
    this.snd_crush.load();

    this.snd_bg = new Audio();
    this.snd_bg.src = "data/bg.ogg";
    this.snd_bg.load();
    this.snd_bg.loop = true;
    this.snd_bg.play();
    this.snd_bg.addEventListener("ended", function(){
            data.snd_bg.currentTime = 0;
            }, true);

    this.patterns = new Array();
    this.img_map = new Image(); 
    this.img_map.src = "data/map.png";
    this.img_map.onload = loaded_callback;

    this.img_logo = new Image();
    this.img_logo.src = "data/title.png";
    this.img_logo.onload = loaded_callback;

    this.img_hero = new Image();
    this.img_hero.src = "data/hero.png";
    this.img_hero.onload = loaded_callback;
    
    this.img_e3 = new Image();
    this.img_e3.src = "data/e3.png";
    this.img_e3.onload = loaded_callback;

    this.img_e2 = new Image();
    this.img_e2.src = "data/e2.png";
    this.img_e2.onload = loaded_callback;

    /*this.img_npup = new Image();
    this.img_npup.src = "data/powerup.png";
    this.img_npup.onload = loaded_callback;
*/
    this.img_pickup = new Image();
    this.img_pickup.src = "data/pickup.png";
    this.img_pickup.onload = loaded_callback;

    this.img_smoke = new Image();
    this.img_smoke .src = "data/smoke.png";
    this.img_smoke.onload = loaded_callback;

    for(i = 0; i < this.numpatterns; i++){
        request = new XMLHttpRequest();
        request.open("GET", "data/p"+i+".txt"); 
        request.onreadystatechange = txt_loaded_callback;
        request.send();
        this.patterns.push(request);
    }

    this.getImage = function(name){
        if(name == "e2"){
            return this.img_e2;
        }else if(name == "pickup"){
            return this.img_pickup;
        }else if(name == "smoke"){
            return this.img_smoke;
        }else if(name == "e3"){
            return this.img_e3;
        }else if(name == "hero"){
            return this.img_hero;
        }else if(name =="pup_blast"){
            return this.img_pickup;
            //return this.img_npup;
        } 
    }
}

function txt_loaded_callback(){
/*    if(data.txt_pattern.readyState == 4){
        data.done--;
    }*/
    if(this.readyState == 4){
        data.done--;
    }
}

function loaded_callback(){
    data.done--;
}
